class WxRequest {
  defaults = {
    baseURL: "",
    url: "",
    data: null,
    method: 'GET',
    header: {
      'Content-type': 'application/json'
    },
    timeout: 60000,
    isLoading: true,
    isPolling: false
  }

  interceptors = {
    request: (config) => config,
    response: (response) => response
  }

  queue = []

  constructor(params = {}) {
    this.defaults = Object.assign({}, this.defaults, params);
  }

  request(options) {
    this.timeId && clearInterval(this.timeId);
    options.url = this.defaults.baseURL + options.url;
    if (options.method !== 'UPLOAD') {
      options.isPolling = options.data.isPolling
    }

    options = {
      ...this.defaults,
      ...options
    }

    if (options.method !== 'UPLOAD' && options.isLoading && !options.isPolling) {
      /*  wx.showLoading({
         title: '加载中',
         mask: true
       }); */
    }

    if (options.isLoading && options.method !== 'UPLOAD') {
      this.queue.push('request');
    }

    options = this.interceptors.request(options);

    return new Promise((resolve, reject) => {
      if (options.method === 'UPLOAD') {
        wx.uploadFile({
          ...options,
          success: (res) => {
            res.data = JSON.parse(res.data);
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            });
            resolve(this.interceptors.response(mergeRes));
          },
          fail: (err) => {
            const mergeErr = Object.assign({}, err, {
              config: options,
              isSuccess: false
            });
            resolve(this.interceptors.response(mergeErr));
          }
        });
      } else {
        wx.request({
          ...options,
          success: (res) => {
            const mergeRes = Object.assign({}, res, {
              config: options,
              isSuccess: true
            });
            resolve(this.interceptors.response(mergeRes));
          },
          fail: (err) => {
            const mergeErr = Object.assign({}, err, {
              config: options,
              isSuccess: false
            });
            reject(this.interceptors.response(mergeErr));
          },
          complete: () => {
            if (options.isLoading && !options.isPolling) {
              wx.hideLoading();
            }
            if (options.isLoading) {
              this.queue.pop();
              if (this.queue.length === 0) {
                clearTimeout(this.timerId);
              }
            }
          }
        });
      }
    });
  }

  get(url, data = {}, config = {}) {
    return this.request(Object.assign({
      url,
      data,
      method: 'GET'
    }, config))
  }

  delete(url, data = {}, config = {}) {
    return this.request(Object.assign({
      url,
      data,
      method: 'DELETE'
    }, config))
  }

  post(url, data = {}, config = {}) {
    return this.request(Object.assign({
      url,
      data,
      method: 'POST'
    }, config))
  }

  put(url, data = {}, config = {}) {
    return this.request(Object.assign({
      url,
      data,
      method: 'PUT'
    }, config))
  }

  all(...promise) {
    return Promise.all(promise)
  }

  upload(url, filePath, name = 'file', config = {}) {
    return this.request(
      Object.assign({
        url,
        filePath,
        name,
        method: 'UPLOAD'
      }, config)
    )
  }
}

export default WxRequest